﻿#include "WidgetRoiDraw.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLabel>
#include <QButtonGroup>
#include <QApplication>
#include <QPainter>
#include <QPixmap>
#include <QFileDialog>
#include "GraphicsScene.h"


#pragma execution_character_set("utf-8")

QMap<DefineItemType,QString> WidgetRoiDraw::mapShapeIconPath = {{DIT_Circle, ":/img/draw_circle.png"},
                                                           {DIT_CircleC, ":/img/draw_circlec.png"},
                                                           {DIT_Rect, ":/img/draw_rect.png"},
                                                           {DIT_RectR, ":/img/draw_rectR.png"},
                                                           {DIT_Polygon, ":/img/draw_polygon.png"},
                                                           {DIT_Caliper, ":/img/draw_caliper.png"},
                                                           {DIT_Line, ":/img/draw_line.png"},
                                                           {DIT_Point, ":/img/draw_point.png"}};

WidgetRoiDraw::WidgetRoiDraw(QWidget *parent)
    : QWidget{parent}
{
    setupUi();
    initConnection();
}

void WidgetRoiDraw::setImage(QImage img)
{
    mImg = img;
    mView->dispImage(img);
}

void WidgetRoiDraw::setupUi()
{
    mView = new GraphicsView;
    btngrpShape = new QButtonGroup(this);
    pbtnRemove = new QPushButton("移除");
    pbtnClear = new QPushButton("清空");
    pbtnOpenImage = new QPushButton("打开图像");
    cbboxDrawMethod = new QComboBox();
    cbboxDrawMethod->addItems({"直接绘制", "添加后修改"});
    for(auto key : ItemBase::mapItemTypeName.keys()){
        QToolButton* btn = new QToolButton();
        btngrpShape->addButton(btn, key);
        btn->setToolTip(ItemBase::mapItemTypeName.value(key));
        btn->setToolButtonStyle(Qt::ToolButtonIconOnly);
        btn->setIcon(QIcon(WidgetRoiDraw::mapShapeIconPath.value(key)));
        btn->setFixedSize(30, 30);
        btn->setIconSize(QSize(30, 30));
    }
    auto hLayout = new QHBoxLayout();
    hLayout->addWidget(new QLabel("绘制方法"));
    hLayout->addWidget(cbboxDrawMethod);
    hLayout->addWidget(pbtnRemove);
    hLayout->addWidget(pbtnClear);
    hLayout->addWidget(pbtnOpenImage);

    for(auto btn : btngrpShape->buttons()){
        hLayout->addWidget(btn);
    }
    hLayout->addStretch();

    auto vLayout = new QVBoxLayout;
    vLayout->addLayout(hLayout);
    vLayout->addWidget(mView);
    this->setLayout(vLayout);

    for(auto btn : btngrpShape->buttons()){
        if(btn != btngrpShape->button(DIT_Rect)){
            btn->setVisible(false);
        }
    }
}

void WidgetRoiDraw::initConnection()
{
    connect(btngrpShape, &QButtonGroup::idClicked, this, &WidgetRoiDraw::onShapeButtonClicked);
    connect(mView->scene, &GraphicsScene::sigCreateFinished, this, &WidgetRoiDraw::onCreateFinished);
    connect(mView->scene, &QGraphicsScene::focusItemChanged, this, &WidgetRoiDraw::sigItemSelectChanged);
    connect(pbtnRemove, &QAbstractButton::clicked, this, [&](){
        ItemBase* item = mView->getSelectItem();
        if(item == nullptr)
            return;
        emit sigRemoveOne(item);
        mView->removeItem(item);
    });
    connect(pbtnClear, &QAbstractButton::clicked, this, [&](){
        emit sigRemoveAll();
        mView->clearItem();
    });
    connect(pbtnOpenImage, &QAbstractButton::clicked, this, [&](){
        QString path = QFileDialog::getOpenFileName(this, "打开图像", QApplication::applicationDirPath(), "");
        if(path == "")
            return;
        QImage img(path);
        mView->dispImage(img);
    });
}

void WidgetRoiDraw::onShapeButtonClicked(const int &id)
{
    bool isDraw = cbboxDrawMethod->currentIndex() == 0;
    DefineItemType type = DefineItemType(id);
    switch (type) {
    case DIT_Circle:
        mItem = isDraw ? new ItemCircle() : new ItemCircle(200,200,300);
    break;
    case DIT_CircleC:
        mItem = isDraw ? new ItemCircleC() : new ItemCircleC(200,200,200,300);
    break;
    case DIT_Rect:
        mItem = isDraw ? new ItemRect() : new ItemRect(200,200,200,200);
    break;
    case DIT_RectR:
        mItem = isDraw ? new ItemRectR() : new ItemRectR(200,200,700,200,M_PI_4);
    break;
    case DIT_Polygon:
    {
        QList<QPointF> points = QList<QPointF>() << QPointF(10, 10) << QPointF(10, 100) << QPointF(100, 100) << QPointF(100, 10);
        mItem = isDraw ? new ItemPolygon() : new ItemPolygon(points);
    }
    break;
    case DIT_Caliper:
        mItem = isDraw ? new ItemCaliper() : new ItemCaliper(0,0,300,200,500);
    break;
    case DIT_Line:
        mItem = isDraw ? new ItemLine() : new ItemLine(0,0,300,200);
    break;
    case DIT_Point:
        mItem = isDraw ? new ItemPoint() : new ItemPoint(300,200);
    break;
    default:
        break;
    }
    mView->addItem(mItem);
    if(isDraw){
        mView->scene->startCreate(type);
        drawStart();
    }
}

void WidgetRoiDraw::drawStart()
{
    isDraw = true;
    for(auto btn : btngrpShape->buttons()){
        btn->setEnabled(false);
    }
    connect(mView->scene, &GraphicsScene::sigPointPush, mItem, &ItemBase::onPointPush);
    connect(mView->scene, &GraphicsScene::sigPointMove, mItem, &ItemBase::onPointMove);
    mView->setFocus();
}

void WidgetRoiDraw::onCreateFinished()
{
    for(auto btn : btngrpShape->buttons()){
        btn->setEnabled(true);
    }
    mItem->onCreateFinish();
    disconnect(mView->scene, &GraphicsScene::sigPointPush, mItem, &ItemBase::onPointPush);
    disconnect(mView->scene, &GraphicsScene::sigPointMove, mItem, &ItemBase::onPointMove);
    if(isDraw){
        emit sigDrawFinish(mItem);
    }
    isDraw = false;
}

void WidgetRoiDraw::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Escape && isDraw){
        isDraw = false;
        onCreateFinished();
        mView->scene->cancelCreate();
        mView->removeItem(mItem);
    }
}


void WidgetRoiDraw::setMode(RoiWorkMode mode)
{
    btngrpShape->button(DIT_Rect)->setVisible(mode == RWM_ModelMatch);
    btngrpShape->button(DIT_RectR)->setVisible(mode == RWM_ModelMatch);
    btngrpShape->button(DIT_Polygon)->setVisible(mode == RWM_ModelMatch);
    btngrpShape->button(DIT_Circle)->setVisible(mode == RWM_ModelMatch);
    btngrpShape->button(DIT_CircleC)->setVisible(mode == RWM_ModelMatch || mode == RWM_CircleFind);
    btngrpShape->button(DIT_Caliper)->setVisible(mode == RWM_LineFind);
    btngrpShape->button(DIT_Line)->setVisible(false);
    btngrpShape->button(DIT_Point)->setVisible(false);
}

void WidgetRoiDraw::setItem(ItemBase *item)
{
    if(mImg.isNull())
        return;
    if(mItem != nullptr){
        mView->removeItem(mItem);
        mItem->deleteLater();
        mItem = nullptr;
    }
    mItem = item;
    mView->addItem(mItem);
}
